 



   .
 2 







 . .
425 




    	2
  	4
 	6
     	7
	9



    



 :       ,          ,    .    ,      .

 :

?Builder -        (, ,  ).       (JSON, XML).
?Strategy -      (BFS, DFS, A*, ),        .  (MazeSolver)      .
?Observer -        ( ,  ,  ).      (GUI, )   -.
?Command -        (undo).       .


  

Builder (TextFileMazeBuilder):
class TextFileMazeBuilder(MazeBuilder):
    def build_from_file(self, filename: str) -> Maze:
        with open(filename, 'r', encoding='utf-8') as f:
            lines = [line.rstrip('\n') for line in f.readlines()]
        
        height = len(lines)
        width = max(len(line) for line in lines) if height > 0 else 0
        maze = Maze(width, height)

        for y, line in enumerate(lines):
            for x, ch in enumerate(line):
                cell = maze.get_cell(x, y)
                if cell is None:
                    continue
                if ch == '#':
                    cell.is_wall = True
                elif ch == 'S':
                    cell.is_start = True
                    maze.start = cell
                elif ch == 'E':
                    cell.is_exit = True
                    maze.exit = cell
                elif ch == ' ':
                    pass
                else:
                    raise ValueError(f"Unknown character '{ch}' at ({x},{y})")

        if maze.start is None or maze.exit is None:
            raise ValueError("Maze must have start (S) and exit (E)")
        return maze
Strategy ( BFS):
class BFSStrategy(PathFindingStrategy):
    def find_path(self, maze: Maze, start: Cell, exit: Cell) -> List[Cell]:
        queue = deque([start])
        came_from = {start: None}
        
        while queue:
            current = queue.popleft()
            if current == exit:
                break
            for nb in maze.get_neighbors(current):
                if nb not in came_from:
                    came_from[nb] = current
                    queue.append(nb)
        
        if exit not in came_from:
            return []
        
        path = []
        cur = exit
        while cur:
            path.append(cur)
            cur = came_from[cur]
        path.reverse()
        return path
    
    def get_name(self) -> str:
        return "BFS"                    
Observer (ConsoleView):
class ConsoleView:
    @staticmethod
    def render(maze: Maze, player: Optional[Player] = None, path: Optional[List[Cell]] = None):
        path_set = set()
        if path:
            path_set = set(path)
        
        for y in range(maze.height):
            line = ""
            for x in range(maze.width):
                cell = maze.get_cell(x, y)
                if not cell:
                    line += " "
                elif player and player.current_cell == cell:
                    line += "P"
                elif cell.is_start:
                    line += "S"
                elif cell.is_exit:
                    line += "E"
                elif cell.is_wall:
                    line += "#"
                elif path and cell in path_set:
                    line += "."
                else:
                    line += " "
            print(line)
        print()
    
    @staticmethod
    def show_stats(stats: SearchStats, algo_name: str):
        print(f"=== {algo_name} Results ===")
        print(stats)
        print()


  (, ).
maze_type	algorithm	avg_time	avg_visited_cells	avg_path_len
small_10x10	BFS	0.08572000006097369	79.0	19.0
small_10x10	DFS	0.039739999920129776	79.0	31.0
small_10x10_	A*	0.13467999997374136	79.0	19.0
small_10x10	Dijkstra	0.11474000057205558	79.0	19.0
medium_50x50	BFS	1.8074600004183594	1874.0	99.0
medium_50x50	DFS	0.5937599995377241	1874.0	429.0
medium_50x50	A*	1.6300600003887666	1874.0	99.0
medium_50x50	Dijkstra	3.1870400001935195	1874.0	99.0
large_100x100	BFS	0.014439999722526409	7033.0	0.0
large_100x100	DFS	0.014839999857940711	7033.0	0.0
large_100x100	A*	0.02542000001994893	7033.0	0.0
large_100x100	Dijkstra	0.02548000011302065	7033.0	0.0
empty_30x30	BFS	0.784620000194991	900.0	59.0
empty_30x30	DFS	0.5252399994787993	900.0	465.
empty_30x30	A*	1.150900000357069	900.0	59.0
empty_30x30	Dijkstra	1.564640000287909	900.0	59.0
no_exit_20x20	BFS	0.2002399993216386	380.	0.0
no_exit_20x20	DFS	0.2512400002160575	380.0	0.0
no_exit_20x20	A*	0.5590400000073714	380.0	0.
no_exit_20x20	Dijkstra	0.35640000060084276	380.0	0.0







     RESULT22.

     

   
?BFS      ,     (    )    .       .
?DFS  - ,      (  ).         ,       .
?A  *      :    ,  BFS,       (  ).      BFS,           .
?      BFS  ,    -  .       (,    ),  BFS    .
  
?Builder     ,      .
?Strategy       (, MazeSolver).          ,     /.
?Observer   -.      PyQt  -          .
?Command  /  (undo/redo)     (,     )    .


 
 -     :
1.      (,  )    .
2.         ,  MazeSolver  .
3.       :  ,  ,  ,  .
4.       ,  mock- ,   .
      
?        MazeSolver    .
?         ,        ,       (Builder).
?   (undo)          .
?     -,         (,    PyQt  ).
 
          :    ,            .
